package c2.cross.business;

import c2.advanced.business.AdvancedBody;
import c2.advanced.business.base.AdvancedModule;
import c2.advanced.business.base.ModuleRequirements;
import c2.advanced.share.DbFacade;
import c2.advanced.share.RpcSuit;
import c2.cross.business.admin.CrossAdminFacade;
import c2.cross.business.arena.ArenaModule;
import c2.cross.business.boss.CrossBossModule;
import c2.cross.business.championrace.ChampionRaceModule;
import c2.cross.business.demo.DemoModule;
import c2.cross.business.guildwar.GuildWarModule;
import c2.cross.business.jungle.JungleModule;
import c2.cross.business.ladder.LadderModule;
import c2.cross.business.minecraft.MinecraftModule;
import c2.cross.business.rank.CrossRankModule;
import c2.cross.server.CrossServerApplication;
import c2.advanced.server.configuration.SetupContext;
import c2.cross.share.*;
import cp.solution.pattern.exception.ThrowingConsumer;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class CrossBody extends AdvancedBody {

    public static String version() {
        return "2023-10-10 17:42";
    }

    @Override
    protected RpcSuit createRpc() {
        return new RpcSuit4Cross();
    }

    // 以下是共享服务区域
    public DbFacade4Cross db = new DbFacade4Cross();

    public CrossAdminFacade admin = new CrossAdminFacade(this);

    @Override
    public DbFacade dbBase() {
        return db;
    }

    // 以下是业务逻辑区域
    public DemoModule demo = new DemoModule(this);
    public LadderModule ladder = new LadderModule(this);
    public MinecraftModule minecraft = new MinecraftModule(this);
    public ArenaModule arena = new ArenaModule(this);
    public CrossRankModule crossRank = new CrossRankModule(this);
    public GuildWarModule guildWar = new GuildWarModule(this);
    public CrossBossModule crossBoss = new CrossBossModule(this);
    public ChampionRaceModule championRace = new ChampionRaceModule(this);
    public JungleModule jungle = new JungleModule(this);

    @Getter
    private final AdvancedModule<?>[] modules = new AdvancedModule[]{common, demo, ladder, minecraft, arena, crossRank, guildWar, crossBoss, championRace, jungle};

    public void setup(SetupContext context) throws Exception {
        time.setup();
        api.setup(context);
        db.setup(context);
        table.setup(context);
        play.setup();
        fightHandler.setUp(play.getPlayBuildContext());

        rpc.setup(context);
    }

    public void initModules(ModuleRequirements requirements) {
        modulesDo(m -> m.initIndependent(requirements), "独立の初始化 initIndependent()");
        // GM注册RPC
        admin.rpcRegister();
        help.rpcRegister();
        modulesDo(AdvancedModule::initDependent, "依赖の初始化 initDependent()");
    }

    private void modulesDo(ThrowingConsumer<AdvancedModule<?>> consumer, String parse) {
        for (AdvancedModule<?> module : modules) {
            log.info("模块[{}] {} 开始", module.getName(), parse);
            long beginTime = System.currentTimeMillis();
            try {
                consumer.accept0(module);
            } catch (Throwable e) {
                moduleFail(module, e, "initIndependent");
            }
            log.info("模块[{}] {} 完成 耗时{}ms", module.getName(), parse, (System.currentTimeMillis() - beginTime));
        }
    }

    private static void moduleFail(AdvancedModule<?> module, Throwable e, String phase) {
        String errMsg = "模块[" + module.getName() + "] " + phase + " 异常, 因为：" + e.getMessage();
        log.error(errMsg, e);
        CrossServerApplication.shutdown(errMsg);
    }

    public void shutdownModules() {
        modulesDo(AdvancedModule::onShutdown, "模块关闭 onShutdown()");
    }
}
